/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.messages.vos.datalist;

import static cn.easyplatform.type.TotalType.AVERAGE;
import static cn.easyplatform.type.TotalType.COUNT;
import static cn.easyplatform.type.TotalType.MAX;
import static cn.easyplatform.type.TotalType.MIN;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.type.FieldType;
import cn.easyplatform.type.Option;
import cn.easyplatform.type.TotalType;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class ListHeaderVo implements Serializable, Option {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private String name;// 列标识

    private String field;// 栏位名称

    private String title;// 标题

    private FieldType type;// 数据类型

    private String sql;// 来源,select name from table where
    // id=$id，一般用在自定义查询,field并不存在本表中

    private String sqlSeparator;// 值是有多个分隔符组成的字符串,配合sql使用

    private boolean isSort;// 是否显示排序功能

    private String width;// 列宽

    private String format;// 格式

    private String component;// 显示的组件

    private boolean isVisible;// 是否可视

    private int totalType;// 统计类型,取代isTotal：1-表示汇总;2-平均;3-表示笔数;4-最大值;5-最小值

    private String totalName;// 汇总的名称

    private String style;// 表头风格

    private String cellStyle;// 单元格风格

    private String totalStyle;// 汇总的风格

    private String groupName;// 分组时的名称

    private String groupStyle;// 分组的风格

    private String event;// 事件表达式

    private String image;// 显示在列头的图标

    private String align;

    private String valign;

    private String iconSclass;

    private String hoverimg;

    private boolean isEditable;// 是否可编辑

    private String draggable;

    private Object instance;// 为了提高性能，由component自定义的实现Cacheable接口，如果为真就保存在这个对象上

    private BigDecimal total;

    private BigDecimal value;

    private int count;

    private boolean export = true;

    private Type optionType;

    private String optionValue;

    public Type getOptionType() {
        return optionType;
    }

    public void setOptionType(Type optionType) {
        this.optionType = optionType;
    }

    public String getOptionValue() {
        return optionValue;
    }

    public void setOptionValue(String optionValue) {
        this.optionValue = optionValue;
    }

    public String getDraggable() {
        return draggable;
    }

    public void setDraggable(String draggable) {
        this.draggable = draggable;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public FieldType getType() {
        return type;
    }

    public void setType(FieldType type) {
        this.type = type;
    }

    public boolean isSort() {
        return isSort;
    }

    public void setSort(boolean isSort) {
        this.isSort = isSort;
    }

    public String getWidth() {
        return width;
    }

    public void setWidth(String width) {
        this.width = width;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getComponent() {
        return component;
    }

    public void setComponent(String component) {
        this.component = component;
    }

    public boolean isVisible() {
        return isVisible;
    }

    public void setVisible(boolean isVisible) {
        this.isVisible = isVisible;
    }

    public int getTotalType() {
        return totalType;
    }

    public void setTotalType(int totalType) {
        this.totalType = totalType;
    }

    public String getTotalName() {
        return totalName;
    }

    public void setTotalName(String totalName) {
        this.totalName = totalName;
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public String getCellStyle() {
        return cellStyle;
    }

    public void setCellStyle(String cellStyle) {
        this.cellStyle = cellStyle;
    }

    public String getTotalStyle() {
        return totalStyle;
    }

    public void setTotalStyle(String totalStyle) {
        this.totalStyle = totalStyle;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getGroupStyle() {
        return groupStyle;
    }

    public void setGroupStyle(String groupStyle) {
        this.groupStyle = groupStyle;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEvent() {
        return event;
    }

    public void setEvent(String event) {
        this.event = event;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getAlign() {
        return align;
    }

    public void setAlign(String align) {
        this.align = align;
    }

    public String getValign() {
        return valign;
    }

    public void setValign(String valign) {
        this.valign = valign;
    }

    public String getIconSclass() {
        return iconSclass;
    }

    public void setIconSclass(String iconSclass) {
        this.iconSclass = iconSclass;
    }

    public String getHoverimg() {
        return hoverimg;
    }

    public void setHoverimg(String hoverimg) {
        this.hoverimg = hoverimg;
    }

    public boolean isEditable() {
        return isEditable;
    }

    public void setEditable(boolean isEditable) {
        this.isEditable = isEditable;
    }

    public Object getInstance() {
        return instance;
    }

    public void setInstance(Object instance) {
        this.instance = instance;
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public String getSqlSeparator() {
        return sqlSeparator;
    }

    public void setSqlSeparator(String sqlSeparator) {
        this.sqlSeparator = sqlSeparator;
    }

    public void caculate(String amount) {
        caculate(amount, false);
    }

    public void caculate(String amount, boolean update) {
        if (total == null)
            reset();
        BigDecimal val = new BigDecimal(amount);
        if (update) {
            total = total.subtract(val);
        } else {
            count++;
            total = total.add(val);
        }
        if (totalType == MAX) {
            if (this.value.compareTo(val) < 0)
                this.value = val;
        } else if (totalType == MIN) {
            if (this.value.compareTo(val) > 0)
                this.value = val;
        }
    }

    public int getCount() {
        return count;
    }

    public double getTotal() {
        return total == null ? 0 : total.doubleValue();
    }

    public double getRawValue() {
        BigDecimal val = null;
        if (totalType == AVERAGE) {
            if (count == 0)
                val = new BigDecimal(0);
            else {
                val = this.total.divide(new BigDecimal(count), 10,
                        BigDecimal.ROUND_HALF_DOWN);
            }
        } else if (totalType == COUNT)
            val = new BigDecimal(count);
        else if (totalType == MAX || totalType == MIN)
            val = this.value;
        else
            val = this.total;
        if (val == null)
            return 0;
        return val.doubleValue();
    }

    public String getValue() {
        double val = getRawValue();
        if (!Strings.isBlank(format))
            return Strings.format(format, val);
        else if (!Strings.isBlank(format)) {
            DecimalFormat fmt = new DecimalFormat(format);
            return fmt.format(val);
        } else {
            DecimalFormat format = new DecimalFormat("###,##0.00");
            return format.format(val);
        }
    }

    public void reset() {
        total = new BigDecimal(0);
        this.value = new BigDecimal(0);
        count = 0;
    }

    public boolean isTotal() {
        return this.totalType != TotalType.NONE;
    }

    @Override
    public String toString() {
        return this.title;
    }

    public boolean isExport() {
        return export;
    }

    public void setExport(boolean export) {
        this.export = export;
    }
}
